package org.wltea.analyzer.neo4j;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.neo4j.cypher.javacompat.ExecutionEngine;
import org.neo4j.cypher.javacompat.ExecutionResult;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.index.Index;
import org.neo4j.kernel.Config;
import org.neo4j.kernel.EmbeddedGraphDatabase;

public class WordRelationsImpl implements WordRelations
{
    String path = "worddb";
    GraphDatabaseService graphDb;
    String name = "word";
    Index<Node> wordIndex;
    ExecutionEngine engine;

    private static WordRelations wordRelations;

    {
        wordRelations = new WordRelationsImpl();
    }

    public static WordRelations getWordRelations()
    {
        return wordRelations;
    }

    private enum RelTypes implements RelationshipType
    {
        ROOT_WORDS, WORD, NEXT_WORD;
    }

    private WordRelationsImpl()
    {
        Map<String, String> configs = new HashMap<String, String>();
        configs.put(Config.DUMP_CONFIGURATION, "true");
        configs.put(Config.READ_ONLY, "true");
        configs.put(Config.USE_MEMORY_MAPPED_BUFFERS, "true");
        configs.put(Config.NODE_STORE_MMAP_SIZE, "1M");
        configs.put(Config.RELATIONSHIP_STORE_MMAP_SIZE, "2M");
        configs.put(Config.PROPERTY_STORE_MMAP_SIZE, "2M");

        graphDb = new EmbeddedGraphDatabase(path);
        wordIndex = graphDb.index().forNodes("words");
        engine = new ExecutionEngine(graphDb);
    }

    @Override
    public List<String> findNextWords(String word)
    {

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("word", word);
        String q = "start a=node:words(word={word}) match a-[r:NEXT-WORD]->x return x.word order by r.count desc";
        ExecutionResult result = engine.execute(q);
        List<String> results = new ArrayList<String>();
        Iterator<String> itrs = result.columnAs("x.word");

        while (itrs.hasNext())
        {
            results.add(itrs.next());
        }
        return results;
    }

    @Override
    public List<String> findNextWords(String word, List<String> nextWords)
    {
        List<String> words = findNextWords(word);
        words.retainAll(nextWords);
        if (null == words || words.size() == 0)
        {
            return nextWords;
        }
        return words;
    }

    @Override
    public String findNextWord(String word, List<String> nextWords)
    {
        List<String> words = findNextWords(word);
        words.retainAll(nextWords);
        if (words.size() > 0)
        {
            return words.get(0);
        }
        return null;
    }

}
